package com.gao.f_reactor.b.server;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author gao
 * @time 2020/08/16 13:17:45
 */
public class Handler implements Runnable {
    public static final int READING = 0, WRITTING = 1;
    private int state;
    private final SocketChannel channel;
    private final Selector selector;
    private final SelectionKey key;

    public Handler(SocketChannel channel, Selector selector) throws IOException {
        this.channel = channel;
        this.selector = selector;
        channel.configureBlocking(false);
        key = this.channel.register(selector, SelectionKey.OP_READ);
        key.attach(this);
        state = READING;
    }

    @Override
    public void run() {
        if (state == READING) {
            read();
        } else if (state == WRITTING) {
            write();
        }
    }

    private String msg = null;

    private void read() {
        try {
            ByteBuffer buffer = ByteBuffer.allocate(100);
            int n = channel.read(buffer);
            buffer.flip();
            byte[] readBytes = new byte[n];
            buffer.get(readBytes);
            msg = new String(readBytes);
            System.out.println("recv: " + msg);

            if ("bye".equalsIgnoreCase(msg)) {
                key.cancel();
                channel.close();
                System.out.println("client退出");
            } else {
                // 处理完read事件之后，下一步就该处理写事件了
                key.interestOps(SelectionKey.OP_WRITE);
                state = WRITTING;
            }
        } catch (IOException e) {
            e.printStackTrace();

        }
    }

    private void write() {
        try {
            if (msg.equalsIgnoreCase("what's the time")) {
                Date now = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                String str = sdf.format(now);
                channel.write(ByteBuffer.wrap(str.getBytes()));
            } else {
                channel.write(ByteBuffer.wrap("it dose not make sense...".getBytes()));
            }
            // 处理完write事件之后，下一步就该处理读事件了
            key.interestOps(SelectionKey.OP_READ);
            state = READING;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
